﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Reflection;
using DCT.Huiteng.Utility.Cache;

namespace DCT.Huiteng.Utility.Web
{
    public class DefaultWebAPIFactory : IWebAPIFactory
    {
        private static string DEFAULT_FUNC_QUERYSTRING = "func";

        KeyValueCache<Type> kvc = null;

        public DefaultWebAPIFactory(List<string> typeFullNameFormat)
        {
            this.TypeFullNameFormat = typeFullNameFormat;
            this.FindTypeHandlers = new List<Func<string, Type>>();
            this.kvc = new KeyValueCache<Type>();
        }

        public List<string> TypeFullNameFormat
        {
            get;
            set;
        }

        public List<Func<string, Type>> FindTypeHandlers
        {
            get;
            set;
        }

        public virtual IWebAPI Create(WebAPIContext context)
        {
            string func = this.GetFunc(context);
            IWebAPI webapi = null;

            if (func != "")
            {
                Type type = this.CreateWebAPIType(func);
                if (type != null)
                {
                    webapi = Activator.CreateInstance(type) as IWebAPI;
                }
            }

            return webapi;
        }

        protected virtual string GetFunc(WebAPIContext context)
        {
            string func = context.Request.QueryString[DEFAULT_FUNC_QUERYSTRING];
            if (func == null)
            {
                func = "";
            }

            return func;
        }

        protected virtual Type CreateWebAPIType(string func)
        {
            Type type = kvc.GetValue(func, key =>
            {
                Type webapitype = null;
                func = func.Replace(":", ".");
                if (!func.EndsWith("webapi", StringComparison.OrdinalIgnoreCase))
                {
                    func = func + "webapi";
                }
                //有先看typeFullNameFormat
                if (webapitype == null && !CollectionUtility.IsEmptyOrNull(this.TypeFullNameFormat))
                {
                    foreach (var format in this.TypeFullNameFormat)
                    {
                        string fullTypeName = string.Format(format, func);
                        webapitype = Type.GetType(fullTypeName, false, true);
                        if (webapitype != null)
                        {
                            break;
                        }
                    }
                }
                //再看FindTypeHandlers
                if (webapitype == null && !CollectionUtility.IsEmptyOrNull(FindTypeHandlers))
                {
                    foreach (var findTypeHandler in this.FindTypeHandlers)
                    {
                        webapitype = findTypeHandler(func);
                        if (webapitype != null)
                        {
                            break;
                        }
                    }
                }

                return webapitype;
            });

            return type;
        }

        public static DefaultWebAPIFactory Init(List<string> typeFullNameFormat)
        {
            DefaultWebAPIFactory obj = new DefaultWebAPIFactory(typeFullNameFormat);
            return obj;
        }
    }
}
